package com.service;
import com.dao.AsAccountDao;
import com.dao.AsAccountDetailDao;
import com.dao.AsSystemConfigDao;
import com.entity.AsAccount;
import com.entity.AsAccountDetail;
import com.entity.AsSystemConfig;
import com.entity.AsUser;
import com.utils.DateUtil;
import com.utils.JsonUtil;
import com.utils.Pager;
import com.utils.PoiUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;

@Service
public class AsAccountDetailService
{
    @Resource
    private AsAccountDetailDao asAccountDetailDao;

    @Resource
    private AsAccountDao asAccountDao;

    @Resource
    private AsSystemConfigDao asSystemConfigDao;

    //返回指定用户的账户交易明细json格式数据
    public String returnAccountDetailOfPageJsonStr(
            Integer userId , Integer page , Integer size ,
            String start , String end , Integer detailType )
    {
        Integer index = ( page -1 ) * size;
        //使用工具将字符串日期格式转换为date
        Date startDate = ( start != null && !("").equals( start ) )? DateUtil.strToDateTime( start ):null;
        Date endDate = ( end != null && !("").equals( end ) )? DateUtil.strToDateTime( end ):null;
        Integer total = asAccountDetailDao.getAccountDetailCountOfPage( userId , startDate , endDate , detailType );
        ArrayList<AsAccountDetail> detailList = asAccountDetailDao.getAccountDetailOfPage( userId , index , size ,startDate , endDate , detailType );
        Pager<AsAccountDetail> pager = new Pager<>();
        pager.setTotal( total );
        pager.setRows( detailList );
        String jsonStr = JsonUtil.toJsonStrWithDateTime( pager );
        //System.out.println( jsonStr );

        return jsonStr;
    }

    //返回所有代理商的流水json数据
    public String returnAgentBalanceReportJsonStr(
            String start , String end ,
            Integer page ,  Integer size )
    {
        Integer index = ( page -1 ) * size;
        //使用工具将字符串日期格式转换为date
        Date startDate = ( start != null && !("").equals( start ) )? DateUtil.strToDateTime( start ):null;
        Date endDate = ( end != null && !("").equals( end ) )? DateUtil.strToDateTime( end ):null;
        Integer total = asAccountDetailDao.getAgentBalanceCount( startDate , endDate );
        ArrayList<Map<String,Object>> detailList = asAccountDetailDao.getAgentBalancePage( startDate , endDate , index , size );
        Pager<Map<String,Object>> pager = new Pager<>();
        pager.setTotal( total );
        pager.setRows( detailList );
        String jsonStr = JsonUtil.toJsonStrWithDateTime( pager );

        return jsonStr;
    }

    //返回指定用户存在的所有交易类型
    public String returnDetailTypeByUserId( Integer userId )
    {
        ArrayList<Map<String,Object>> detailTypeList = asAccountDetailDao.getDetailTypeByUserId( userId );
        String jsonStr = JsonUtil.toJsonStr( detailTypeList );
        //System.out.println( jsonStr );

        return jsonStr;
    }

    //财务操作资金变动(增加乐观锁)
    @Transactional(rollbackFor = Exception.class)
    public Integer submitFinancialOperate( AsAccountDetail detail , AsUser user , String userName )
    {
        Integer resultCode = 0;
        Integer userId = detail.getUserId();
        Double operateMoney = detail.getMoney();
        Integer detailType = detail.getDetailType();
        //根据用户id获取其账户
        AsAccount userAccount = asAccountDao.getAccountByUserId( userId );
        Double totalMoney = userAccount.getMoney();
        Double currentMoney = totalMoney + ( operateMoney );
        userAccount.setMoney( currentMoney );
        userAccount.setMoneyBak( currentMoney );
        //将资金变动写入用户账户
        resultCode = asAccountDao.updateAccount( userAccount );
        //System.out.println( "第一次: " + resultCode );

        //查询财务人员账户信息
        AsAccount financialAccount = new AsAccount();
        Map<String,Object> map = asAccountDao.getFinancialUserAccount();
        Double financialTotalMoney = (Double)map.get( "money" );
        Double financialCurrentMoney = financialTotalMoney - ( operateMoney );
        //获取财务账户version
        Integer financialVersion = (Integer)map.get( "version" );
        System.out.println( "断点前");
        System.out.println( "version: " + financialVersion );
        System.out.println( "断点后");
        financialAccount.setUserId( (Integer)map.get( "userId" ) );
        financialAccount.setMoney( financialCurrentMoney );
        financialAccount.setMoneyBak( financialCurrentMoney );
        financialAccount.setVersion( financialVersion );
        //将资金变动写入财务账户
        resultCode *= asAccountDao.updateAccount( financialAccount );
        //System.out.println( "第二次: " + resultCode );

        //向账户明细表中添加数据
        //查询财务款项操作名称
        detail.setMoney( Math.abs( operateMoney ) );
        detail.setAccountMoney( currentMoney );
        detail.setDetailDateTime( new Date() );
        detail.setMemo( "[" + user.getUserName() + "]对用户[" + userName + "]进行了" +
                detail.getDetailTypeName() + "操作; " + (operateMoney>0?"增加":"扣除") + "[" + userName + "]资金:"
                + Math.abs( operateMoney ) + "元; 其它: " + detail.getMemo() );
        detail.setDetailTypeName( "[员工操作]" + detail.getDetailTypeName() );
        resultCode *= asAccountDetailDao.addOneDetail( detail );
        //System.out.println( "第三次: " + resultCode );
        //确保任意步骤执行失败(resultCode为0)后回滚
        if( resultCode == 0 )
        {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return resultCode;
    }

    //生成代理商流水excel
    public String createAgentBalanceExcel( String path )
    {
        //设置excel标题
        String excelTitle = "代理商流水报表";
        //设置列名
        LinkedHashMap<String,String> columnTitle = new LinkedHashMap<>();
        columnTitle.put( "序号" , "id" );
        columnTitle.put( "代理商名称" , "userName" );
        columnTitle.put( "账务资金" , "money" );
        columnTitle.put( "账户余额" , "accountMoney" );
        columnTitle.put( "备注信息" , "memo" );
        columnTitle.put( "交易时间" , "detailDateTime" );
        //获取全部代理商流水
        ArrayList<Map<String,Object>> content = asAccountDetailDao.getAgentBalancePage( null,null,null,null );
        for( Map<String,Object> map : content )
        {
            for( Map.Entry<String,Object> x : map.entrySet() )
            {
                if( x.getValue().getClass() == Date.class )
                {
                    //将date转换为字符串
                    String str = DateUtil.dateToStr( (Date)x.getValue() );
                    map.put( x.getKey() , str );
                }
                else
                {
                    map.put( x.getKey() , x.getValue().toString() );
                }
            }
        }
        PoiUtil poi = new PoiUtil( 5500 , (short)800 );
        return poi.createExcel( excelTitle , columnTitle , content , path );
    }
}
